package com.antd.auth.filter;

import cn.hutool.core.util.StrUtil;
import com.antd.common.auth.exception.ValidateCodeException;
import com.antd.common.core.constant.AntdConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

/**
 * TODO
 *
 * @author 子丶沫
 * @version 1.0
 * @date 2020/12/2 17:00
 */
@Slf4j
@Component
public class SmsCodeAuthFilter extends OncePerRequestFilter {

    @Autowired
    private StringRedisTemplate redisTemplate;

    private Set<String> urls=new HashSet<>();

    private AntPathMatcher pathMatcher=new AntPathMatcher();

    @Autowired
    private AuthenticationFailureHandler authenticationFailureHandler;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        boolean action=false;
        for(String url:urls){
            if(pathMatcher.match(url,request.getRequestURI())){
                action=true;
                break;
            }
        }
        if(action){
            try{
                validate(request);
            }catch (ValidateCodeException e){
                e.printStackTrace();
                authenticationFailureHandler.onAuthenticationFailure(request,response,e);
                return;
            }
        }
        filterChain.doFilter(request,response);
    }

    @Override
    public void afterPropertiesSet() throws ServletException {
        super.afterPropertiesSet();
        urls.add("/mobile/login");
    }

    private void validate(HttpServletRequest request){
        String smsCode = request.getParameter("smsCode");
        if(StrUtil.isBlank(smsCode)){
            throw new ValidateCodeException("验证码为空");
        }
        String mobile=request.getParameter("mobile");
        if(StrUtil.isBlank(mobile)){
            throw new ValidateCodeException("手机号码为空");
        }
        String key=AntdConstant.ANTD_SMS_CODE_KEY+mobile;
        String code = redisTemplate.opsForValue().get(key);
        if(StrUtil.isBlank(code)){
            throw new ValidateCodeException("验证码已过期");
        }
        if(!smsCode.equalsIgnoreCase(code)){
            throw new ValidateCodeException("验证码错误");
        }
        redisTemplate.delete(key);
    }
}
